<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Obtaining the Size of a Unit In the Last Place - ULP</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 4.2.1">
<link rel="up" href="../next_float.html" title="Floating-Point Representation Distance (ULP), and Finding Adjacent Floating-Point Values">
<link rel="prev" href="float_advance.html" title="Advancing a floating-point Value by a Specific Representation Distance (ULP) float_advance">
<link rel="next" href="../float_comparison.html" title="Floating-point Comparison">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="float_advance.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../next_float.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../float_comparison.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.next_float.ulp"></a><a class="link" href="ulp.html" title="Obtaining the Size of a Unit In the Last Place - ULP">Obtaining the Size of a
      Unit In the Last Place - ULP</a>
</h3></div></div></div>
<p>
        Function <code class="computeroutput"><span class="identifier">ulp</span></code> gives the size
        of a unit-in-the-last-place for a specified floating-point value.
      </p>
<h5>
<a name="math_toolkit.next_float.ulp.h0"></a>
        <span class="phrase"><a name="math_toolkit.next_float.ulp.synopsis"></a></span><a class="link" href="ulp.html#math_toolkit.next_float.ulp.synopsis">Synopsis</a>
      </h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">ulp</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">FPT</span><span class="special">&gt;</span>
<span class="identifier">FPT</span> <span class="identifier">ulp</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">FPT</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">FPT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Policy</span><span class="special">&gt;</span>
<span class="identifier">FPT</span> <span class="identifier">ulp</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">FPT</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Policy</span><span class="special">&amp;);</span>

<span class="special">}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.next_float.ulp.h1"></a>
        <span class="phrase"><a name="math_toolkit.next_float.ulp.description_ulp"></a></span><a class="link" href="ulp.html#math_toolkit.next_float.ulp.description_ulp">Description
        - ulp</a>
      </h5>
<p>
        Returns one <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place" target="_top">unit
        in the last place</a> of <span class="emphasis"><em>x</em></span>.
      </p>
<p>
        Corner cases are handled as follows:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            If the argument is a NaN, then raises a <a class="link" href="../error_handling.html#math_toolkit.error_handling.domain_error">domain_error</a>.
          </li>
<li class="listitem">
            If the argument is an infinity, then raises an <a class="link" href="../error_handling.html#math_toolkit.error_handling.overflow_error">overflow_error</a>.
          </li>
<li class="listitem">
            If the argument is zero then returns the smallest representable value:
            for example for type <code class="computeroutput"><span class="keyword">double</span></code>
            this would be either <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">min</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">denorm_min</span><span class="special">()</span></code> depending whether denormals are supported
            (which have the values <code class="computeroutput"><span class="number">2.2250738585072014e-308</span></code>
            and <code class="computeroutput"><span class="number">4.9406564584124654e-324</span></code>
            respectively).
          </li>
<li class="listitem">
            If the result is too small to represent, then returns the smallest representable
            value.
          </li>
<li class="listitem">
            Always returns a positive value such that <code class="computeroutput"><span class="identifier">ulp</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">ulp</span><span class="special">(-</span><span class="identifier">x</span><span class="special">)</span></code>.
          </li>
</ul></div>
<p>
        <span class="bold"><strong>Important:</strong></span> The behavior of this function
        is aligned to that of <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ulp%28double%29" target="_top">Java's
        ulp function</a>, please note however that this function should only
        ever be used for rough and ready calculations as there are enough corner
        cases to trap even careful programmers. In particular:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            The function is asymmetrical, which is to say, given <code class="computeroutput"><span class="identifier">u</span>
            <span class="special">=</span> <span class="identifier">ulp</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code> if <code class="computeroutput"><span class="identifier">x</span>
            <span class="special">&gt;</span> <span class="number">0</span></code>
            then <code class="computeroutput"><span class="identifier">x</span> <span class="special">+</span>
            <span class="identifier">u</span></code> is the next floating-point
            value, but <code class="computeroutput"><span class="identifier">x</span> <span class="special">-</span>
            <span class="identifier">u</span></code> is not necessarily the previous
            value. Similarly, if <code class="computeroutput"><span class="identifier">x</span> <span class="special">&lt;</span> <span class="number">0</span></code>
            then <code class="computeroutput"><span class="identifier">x</span> <span class="special">-</span>
            <span class="identifier">u</span></code> is the previous floating-point
            value, but <code class="computeroutput"><span class="identifier">x</span> <span class="special">+</span>
            <span class="identifier">u</span></code> is not necessarily the next
            value. The corner cases occur at power of 2 boundaries.
          </li>
<li class="listitem">
            When the argument becomes very small, it may be that there is no floating-point
            value that represents one ULP. Whether this is the case or not depends
            not only on whether the hardware may <span class="emphasis"><em>sometimes</em></span> support
            denormals (as signalled by <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">has_denorm_now</span><span class="special">&lt;</span><span class="identifier">FPT</span><span class="special">&gt;()</span></code>), but also whether these are currently
            enabled at runtime (for example on SSE hardware, the DAZ or FTZ flags
            will disable denormal support). In this situation, the <code class="computeroutput"><span class="identifier">ulp</span></code> function may return a value that
            is many orders of magnitude too large.
          </li>
</ul></div>
<p>
        In light of the issues above, we recommend that:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            To move between adjacent floating-point values always use <a class="link" href="float_next.html" title="Finding the Next Greater Representable Value (float_next)">float_next</a>,
            <a class="link" href="float_prior.html" title="Finding the Next Smaller Representable Value (float_prior)">float_prior</a>
            or <a class="link" href="nextafter.html" title="Finding the Next Representable Value in a Specific Direction (nextafter)">nextafter</a>
            (<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">nextafter</span></code> is another candidate, but
            our experience is that this also often breaks depending which optimizations
            and hardware flags are in effect).
          </li>
<li class="listitem">
            To move several floating-point values away use <a class="link" href="float_advance.html" title="Advancing a floating-point Value by a Specific Representation Distance (ULP) float_advance">float_advance</a>.
          </li>
<li class="listitem">
            To calculate the edit distance between two floats use <a href="../../../../../../libs/math/doc/html/math_toolkit/next_float/float_distance.html" target="_top">Boost.Math
            float_distance</a>.
          </li>
</ul></div>
<p>
        There is none the less, one important use case for this function:
      </p>
<p>
        If it is known that the true result of some function is x<sub>t</sub> and the calculated
        result is x<sub>c</sub>, then the error measured in ulp is simply <code class="literal">fabs(x<sub>t</sub> -
        x<sub>c</sub>) / ulp(x<sub>t</sub>)</code>.
      </p>
</div>
<div class="copyright-footer">Copyright © 2006-2021 Nikhar Agrawal, Anton Bikineev, Matthew Borland,
      Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert Holin, Bruno
      Lalande, John Maddock, Evan Miller, Jeremy Murphy, Matthew Pulver, Johan Råde,
      Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle
      Walker and Xiaogang Zhang<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="float_advance.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../next_float.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../float_comparison.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
